package com.example.myproject.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.myproject.dto.torrent.TorrentRecommendationDTO;
import com.example.myproject.mapper.DownloadRecordMapper;
import com.example.myproject.mapper.TorrentMapper;
import com.example.myproject.mapper.TorrentTagMapper;
import com.example.myproject.model.DownloadRecord;
import com.example.myproject.model.Torrent;
import com.example.myproject.service.RecommendationService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
public class RecommendationServiceImpl implements RecommendationService {

    @Autowired
    private TorrentMapper torrentMapper;
    @Autowired
    private TorrentTagMapper torrentTagMapper;
    @Autowired
    private DownloadRecordMapper downloadRecordMapper;

    private static final int NEW_USER_DOWNLOAD_THRESHOLD = 2;



    private Page<Torrent> getHotTorrents(int page, int size) {
        Page<Torrent> pageParam = new Page<>(page, size);
        QueryWrapper<Torrent> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByDesc("download_count")
                .orderByDesc("score");
        return torrentMapper.selectPage(pageParam, queryWrapper);
    }

    private Page<Torrent> getCategoryBasedRecommendations(Long userId, List<DownloadRecord> downloadHistory, int page, int size) {
        // 1. 获取用户已下载过的资源ID列表
        Set<Long> downloadedTorrentIds = downloadHistory.stream()
                .map(DownloadRecord::getTorrentId)
                .collect(Collectors.toSet());

        // 2. 获取用户下载过的资源类别及其下载次数
        Map<Long, Long> categoryDownloadCount = new HashMap<>();
        for (DownloadRecord record : downloadHistory) {
            Torrent torrent = torrentMapper.selectById(record.getTorrentId());
            if (torrent != null) {
                categoryDownloadCount.merge(torrent.getCategoryId(), 1L, Long::sum);
            }
        }

        // 3. 找出下载次数最多的类别
        Optional<Map.Entry<Long, Long>> mostDownloadedCategory = categoryDownloadCount.entrySet()
                .stream()
                .max(Map.Entry.comparingByValue());

        if (mostDownloadedCategory.isPresent()) {
            // 4. 获取该类别中评分最高且未下载过的资源
            Page<Torrent> pageParam = new Page<>(page, size);
            QueryWrapper<Torrent> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("category_id", mostDownloadedCategory.get().getKey())
                    .notIn("torrent_id", downloadedTorrentIds)  // 排除已下载的资源
                    .orderByDesc("score")
                    .orderByDesc("download_count");
            return torrentMapper.selectPage(pageParam, queryWrapper);
        } else {
            // 如果没有找到类别，返回未下载过的热门资源
            return getHotTorrentsExcludingDownloaded(page, size, downloadedTorrentIds);
        }
    }

    private Page<Torrent> getHotTorrentsExcludingDownloaded(int page, int size, Set<Long> downloadedTorrentIds) {
        Page<Torrent> pageParam = new Page<>(page, size);
        QueryWrapper<Torrent> queryWrapper = new QueryWrapper<>();
        queryWrapper.notIn("torrent_id", downloadedTorrentIds)  // 排除已下载的资源
                .orderByDesc("download_count")
                .orderByDesc("score");
        return torrentMapper.selectPage(pageParam, queryWrapper);
    }

    @Override
    public List<Torrent> getSimilarTorrents(Long torrentId, int limit) {
        // 1. 获取当前资源信息
        Torrent currentTorrent = torrentMapper.selectById(torrentId);
        if (currentTorrent == null) {
            return Collections.emptyList();
        }

        // 2. 基于类别和标签查找相似资源
        QueryWrapper<Torrent> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("category_id", currentTorrent.getCategoryId())
                .ne("torrent_id", torrentId)
                .orderByDesc("score")
                .last("LIMIT " + limit);

        return torrentMapper.selectList(queryWrapper);
    }


    @Override
    public Page<TorrentRecommendationDTO> getPersonalizedRecommendations(Long userId, int page, int size) {
        // 1. 获取用户下载历史
        QueryWrapper<DownloadRecord> recordQuery = new QueryWrapper<>();
        recordQuery.eq("user_id", userId)
                .eq("is_complete", true);
        List<DownloadRecord> downloadHistory = downloadRecordMapper.selectList(recordQuery);

        // 2. 判断用户类型
        Page<Torrent> torrentPage;
        if (downloadHistory.size() < NEW_USER_DOWNLOAD_THRESHOLD) {
            // 新用户或下载量少的用户：推荐下载量最高的资源
            torrentPage = getHotTorrents(page, size);
        } else {
            // 老用户：推荐最常下载类别的评分最高且未下载过的资源
            torrentPage = getCategoryBasedRecommendations(userId, downloadHistory, page, size);
        }

        // 3. 转换为DTO并添加标签信息
        Page<TorrentRecommendationDTO> dtoPage = new Page<>(torrentPage.getCurrent(), torrentPage.getSize(), torrentPage.getTotal());
        List<TorrentRecommendationDTO> dtoList = torrentPage.getRecords().stream().map(torrent -> {
            TorrentRecommendationDTO dto = new TorrentRecommendationDTO();
            BeanUtils.copyProperties(torrent, dto);

            // 获取标签信息
            List<Long> tagIds = torrentTagMapper.selectTagIdsByTorrentId(torrent.getTorrentId());
            List<String> tagNames = torrentTagMapper.selectTagNamesByTorrentId(torrent.getTorrentId());

            dto.setTagIds(tagIds);
            dto.setTagNames(tagNames);

            // 将分数保留两位小数
            if (dto.getScore() != null) {
                dto.setScore(Math.round(dto.getScore() * 100.0) / 100.0);
            }

            return dto;
        }).collect(Collectors.toList());

        dtoPage.setRecords(dtoList);
        return dtoPage;
    }

}